﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace Tools.Types {
	[TypeConverter(typeof(SpriteCfgConverter))]
	public class SpriteCfg {
		[CategoryAttribute("General"), DescriptionAttribute("Name of the Sprite.")]
		public string Name { get; set; }

		[CategoryAttribute("General"), DescriptionAttribute("Name of rendered texture.")]
		[Editor(typeof(AssetSelectorEditor), typeof(UITypeEditor))]
		[AssetPathHandler(typeof(TexturePathHandler))]
		public string TextureName { get; set; }

		[CategoryAttribute("General"), DescriptionAttribute("Name of mask texture for physics.")]
		[Editor(typeof(AssetSelectorEditor), typeof(UITypeEditor))]
		[AssetPathHandler(typeof(TexturePathHandler))]
		public string MaskTextureName { get; set; }

		[CategoryAttribute("Positioning"), DescriptionAttribute("Offset from frame positions to the center.")]
		public Vector2 Center { get; set; }

		[CategoryAttribute("Positioning"), DescriptionAttribute("Width and Height of sprite.")]
		public Vector2 Size { get; set; }

		[CategoryAttribute("Animation"), DescriptionAttribute("Top left position of every frame for this sprite.")]
		[TypeConverter(typeof(Vector2.ListConverter))]
		public List<Vector2> Frames { get; set; }

		[CategoryAttribute("Animation"), DescriptionAttribute("Sequences of animations.")]
		[TypeConverter(typeof(SpriteSequenceCfg.ListConverter))]
		public List<SpriteSequenceCfg> Sequences { get; set; }

		// ----------

		public SpriteCfg() {
			Name = "Sprite";
			TextureName = "Missing";
			MaskTextureName = "Missing";
			Center = Vector2.Zero;
			Size = new Vector2( 1f, 1f );
			Frames = new List<Vector2>();
			Sequences = new List<SpriteSequenceCfg>();
		}

		// ----------

		private class SpriteCfgConverter : TypeConverter {
			public override bool GetPropertiesSupported( ITypeDescriptorContext context ) {
				return true;
			}

			public override PropertyDescriptorCollection GetProperties( ITypeDescriptorContext context, object value, Attribute[] attributes ) {
				PropertyDescriptorCollection pd = TypeDescriptor.GetProperties( typeof(SpriteCfg), attributes );

				// Create sorting
				string[] sorting = new string[] {
					"Name",
					"TextureName",
					"MaskTextureName",
					"Size",
					"Center",
					"Frames",
					"Sequences"
				};

				return pd.Sort( sorting );
			}
		}
	}

	public class SpriteSequenceCfg {
		[CategoryAttribute("General"), DescriptionAttribute("Name of the sequence.")]
		public string Name { get; set; }
			
		[CategoryAttribute("General"), DescriptionAttribute("Frames per second.")]
		public float FrameRate { get; set; }
			
		[CategoryAttribute("General"), DescriptionAttribute("First, inclusive, frame for this sequence.")]
		public int StartFrame { get; set; }
			
		[CategoryAttribute("General"), DescriptionAttribute("Last, inclusive, frame for this sequence.")]
		public int EndFrame { get; set; }
			
		[CategoryAttribute("General"), DescriptionAttribute("Indicates if this sequence loops.")]
		public bool Loop { get; set; }

		// ----------

		public SpriteSequenceCfg() {
			Name = "Idle";
			FrameRate = 0;
			StartFrame = 0;
			EndFrame = 0;
			Loop = false;
		}

		// ----------

		public override string ToString() {
			return Name;
		}

		// ----------

		
		public class ListConverter : TypeConverter {
			public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType ) {
				if( destinationType == typeof(string) ) {
					List<SpriteSequenceCfg> list = (List<SpriteSequenceCfg>)value;
					return String.Join( ", ", (object[])list.ToArray() );
				}

				return base.ConvertTo( context, culture, value, destinationType );
			}
		}
	}
}
